package qualomelhor.database;

import java.util.Date;
import java.util.ArrayList;
import java.util.HashMap;
import javax.persistence.Id;
import qualomelhor.database.ParametrosSistema.SiteHost;
import qualomelhor.gwt.modules.client.ClientUtils;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Indexed;
import com.googlecode.objectify.annotation.Serialized;
import java.io.Serializable;

@Entity
public class Comparacao implements Serializable {

	public static enum TipoComparacao {
		TIPO_COMPARACAO_1_PRODUTO((byte)0, "Comparacao item"),
		TIPO_COMPARACAO_2_PRODUTOS((byte)1, "Comparacao 2 itens"),
		TIPO_COMPARACAO_3_PRODUTOS((byte)2, "Comparacao 3 itens");

		public static TipoComparacao getComparacaoPorId(int id) {
			TipoComparacao result = null;
			for (int i = 0; i < TipoComparacao.values().length; i++) {
				if (TipoComparacao.values()[i].getIdTipoComparacao() == id) {
					result = TipoComparacao.values()[i];
					break;
				}
			}
			return result;
		}

		private TipoComparacao(byte id, String desc) {
			idTipoComparacao = id;
			descricao = desc;
		}

		public byte getIdTipoComparacao() {
			return idTipoComparacao;
		}

		public String getDescricao() {
			return descricao;
		}

		private byte idTipoComparacao;
		private String descricao;
	};

	private static final long serialVersionUID = 0;

    @Id
    private Long id; 

    private TipoComparacao tipoComparacao;

    private ArrayList<Long> listProdutosComp;

    @Indexed
    private SiteHost site;

    @Indexed
    private String locale;

    @Serialized
    private ArrayList<VotoComparacaoProduto> listVotoComparacaoProdutos;

    @Serialized
    private ArrayList<PathComparacao> listPathComparacao;

    @Serialized
    private Avatar avatar;

    @Serialized
    private HashMap<Long, String> mapNomeProdComp;

    private Long idUsuario;

    @Indexed
    private String linkBlog;

    private String nomeBlog;

    private Long idUsuarioLink;

    @Indexed
    private int diasCheckLink;

    @Indexed
    private Date dataInclusao;

    private String schemaMain;

    private String schemaExtend;

    @Indexed
    private String linkImgVersus;

    @Serialized
    private ArrayList<String> listSharesFB_Id;

	@Override public boolean equals(Object aThat) {
		if ( this == aThat ) return true;

        if ( !(aThat instanceof Comparacao) ) return false;

        Comparacao that = (Comparacao)aThat;
        return this.getId().equals(that.getId());
	}

    public Comparacao() {

    }

    public Comparacao(TipoComparacao tipoComparacao, ArrayList<Long> listProdutosComp, SiteHost site, String locale, ArrayList<VotoComparacaoProduto> listVotoComparacaoProdutos, ArrayList<PathComparacao> listPathComparacao, Avatar avatar, HashMap<Long, String> mapNomeProdComp, Long idUsuario, Date dataInclusao) {
    	this.tipoComparacao = tipoComparacao;
    	this.listProdutosComp = listProdutosComp;
    	this.site = site;
    	this.locale = locale;
        this.listVotoComparacaoProdutos = listVotoComparacaoProdutos;
        this.listPathComparacao = listPathComparacao;
        this.avatar = avatar;
        this.mapNomeProdComp = mapNomeProdComp;
        this.idUsuario = idUsuario;
        this.idUsuarioLink = 0L;
        this.linkBlog = "";
        this.nomeBlog = "";
        this.diasCheckLink = 0;
        this.dataInclusao = dataInclusao;
        this.schemaMain = "BlogPosting";
        this.schemaExtend = "";
        this.linkImgVersus = "";
        this.listSharesFB_Id = new ArrayList<String>(0);
    }

    public Long getId() { 
        return id; 
    } 

    public TipoComparacao getTipoComparacao() { 
        return tipoComparacao;
    }

    public boolean jaVotou(Long idUsuario, String ipAddress) {
    	boolean result = false;
    	for (VotoComparacaoProduto v: listVotoComparacaoProdutos) {
    		if (v.getIdUsuario().equals(idUsuario) || v.getIpUser().equals(ipAddress)) {
    			result = true;
    			break;
    		}
    	}
    	return result;
    }

    public VotoComparacaoProduto getVotoAtual(Long idUsuario) {
    	VotoComparacaoProduto result = null;
    	for (VotoComparacaoProduto v: listVotoComparacaoProdutos) {
    		if (v.getIdUsuario().equals(idUsuario)) {
    			result = v;
    			break;
    		}
    	}
    	return result;
    }

    public VotoComparacaoProduto getVotoAtual(String ipAddress) {
    	VotoComparacaoProduto result = null;
    	for (VotoComparacaoProduto v: listVotoComparacaoProdutos) {
    		if (v.getIpUser().equals(ipAddress)) {
    			result = v;
    			break;
    		}
    	}
    	return result;
    }

    public boolean jaVotou(Long idUsuario) {
    	boolean result = false;
    	for (VotoComparacaoProduto v: listVotoComparacaoProdutos) {
    		if (v.getIdUsuario().equals(idUsuario)) {
    			result = true;
    			break;
    		}
    	}
    	return result;
    }

    public boolean jaVotou(String ipAddress) {
    	boolean result = false;
    	for (VotoComparacaoProduto v: listVotoComparacaoProdutos) {
    		if (v.getIpUser().equals(ipAddress)) {
    			result = true;
    			break;
    		}
    	}
    	return result;
    }

    public ArrayList<Long> getListProdutosComp() { 
        return listProdutosComp;
    }

    public SiteHost getSiteOriginal() {
    	return site;
    }

    public String getLocale() {
    	return locale;
    }

    public ArrayList<VotoComparacaoProduto> getListVotoComparacaoProdutos() {
    	return listVotoComparacaoProdutos;
    }

    public ArrayList<PathComparacao> getListPathComparacao() {
    	return listPathComparacao;
    }

    public Avatar getAvatar() {
    	return avatar;
    }

    public HashMap<Long, String> getMapNomeProdComp() {
    	return mapNomeProdComp;
    }

    public Long getIdUsuario() { 
        return idUsuario;
    }

    public Long getIdUsuarioLink() {
    	return idUsuarioLink;
    }

    public String getLinkBlog() {
    	return linkBlog;
    }

    public String getNomeBlog() {
    	return nomeBlog;
    }

    public int getDiasCheckLink() {
    	return diasCheckLink;
    }

    public String getSchemaMain() {
    	return schemaMain;
    }

    public String getSchemaExtend() {
    	return schemaExtend;
    }

    public String getLinkImageVersus() {
    	return linkImgVersus;
    }

    public ArrayList<String> getListSharesID_FB() {
    	return listSharesFB_Id;
    }

    public Date getDataInclusao() { 
    	return dataInclusao; 
	}

	public void setId(Long id) {
		this.id = id;
	}

	public void setTipoComparacao(TipoComparacao tipoComparacao) {
		this.tipoComparacao = tipoComparacao;
    }

    public void setListProdutoComp(ArrayList<Long> listProdutoComp) {
    	this.listProdutosComp = listProdutoComp;
    }

    public void setSiteOriginal(SiteHost site) {
    	this.site = site;
    }

    public void setLocale(String locale) {
    	this.locale = locale;
    }

    public void setListVotoComparacaoProdutos (ArrayList<VotoComparacaoProduto> listVotoComparacaoProdutos) {
    	this.listVotoComparacaoProdutos = listVotoComparacaoProdutos;
    }

    public void setListPathComparacao (ArrayList<PathComparacao> listPathComparacao) {
    	this.listPathComparacao = listPathComparacao;
    }

    public void setAvatar (Avatar avatar) {
    	this.avatar = avatar;
    }

    public void setMapNomeProdComp(HashMap<Long, String> mapNomeProdComp) {
    	this.mapNomeProdComp = mapNomeProdComp;
    }

    public void setIdUsuario(Long idUsuario) {
    	this.idUsuario = idUsuario;
    }

    public void setIdUsuarioLink(Long idUsuarioLink) {
    	this.idUsuarioLink = idUsuarioLink;
    }

    public void setLinkBlog(String linkBlog) {
    	this.linkBlog = linkBlog;
    }

    public void setNomeBlog(String nomeBlog) {
    	this.nomeBlog = nomeBlog;
    }

    public void setDiasCheckLink(int diasCheckLink) {
    	this.diasCheckLink = diasCheckLink;
    }

    public void setSchemaMain(String schemaMain) {
    	this.schemaMain = schemaMain;
    }

    public void setSchemaExtend(String schemaExtend) {
    	this.schemaExtend = schemaExtend;
    }

    public void setLinkImageVersus(String linkImageVersus) {
    	this.linkImgVersus = linkImageVersus;
    }

    public void setListSharesFB_Id(ArrayList<String> listSharesFB_Id) {
    	this.listSharesFB_Id = listSharesFB_Id;
    }

    public void setDataInclusao(Date dataInclusao) { 
    	this.dataInclusao = dataInclusao; 
	}

    public String getPath(SiteHost site) {
    	String result = "";
    	for (int i = 0; i < getListPathComparacao().size(); i++) {
    		if (getListPathComparacao().get(i).getSite().equals(site)) {
    			result = getListPathComparacao().get(i).getPath();
    			break;
    		}
    	}
    	if (getListPathComparacao().size() > 0 && result.equals("")) {
    		result = getListPathComparacao().get(0).getPath();
    	}
    	return result;
    }

    public PathComparacao getPathComparacao(SiteHost site, String locale) {
    	PathComparacao result = null;
    	if (locale == null) { 
    		locale = "en_US";
    	}
    	if (site == null) {
    		site = SiteHost.SITE_QUALQUER;
    	}

    	//Se o locale eh diferente do site, tenta achar o path de um site com o mesmo locale
    	if (!site.getLocale()[0].equals(locale)) {    	
    		for (PathComparacao path: listPathComparacao) {
    			if (path.getSite().getLocale()[0].indexOf(locale) == 0) {
    				result = path;
    				break;
    			}
    		}
    	}

    	//Se nao achou entao tenta achar pelo site
    	if (result == null) {
        	for (PathComparacao path: listPathComparacao) {
        		if (path.getSite().equals(site)) {
        			result = path;
        			break;
        		}
        	}
    	}

    	//Se nao achou tenta pelo site original da comparacao
    	if (result == null) {
    		for (PathComparacao path: listPathComparacao) {
        		if (path.getSite().equals(this.site)) {
        			result = path;
        			break;
        		}
        	}
    	}

    	//E por fim se nao achou pega a primeira que tiver
    	if (result == null && getListPathComparacao().size() > 0) {
    		result = getListPathComparacao().get(0);
    	}
    	return result;
    }

    /*
    public PathComparacao getPathComparacao(SiteHost site) {
    	PathComparacao result = null;
    	for (PathComparacao path: listPathComparacao) {
    		if (path.getSite().equals(site)) {
    			result = path;
    			break;
    		}
    	}
    	if (result == null) {
    		for (PathComparacao path: listPathComparacao) {
        		if (path.getSite().equals(this.site)) {
        			result = path;
        			break;
        		}
        	}
    	}
    	if (result == null && getListPathComparacao().size() > 0) {
    		result = getListPathComparacao().get(0);
    	}
    	return result;
    }
    */

    /*
    public String getPergunta() {
    	String result = "";
    	if (site.equals(SiteHost.SITE_QUALQUER)) {
    		result = getComplementoPergunta();
    	} else {
    		result = site.getPergunta() + " " + getComplementoPergunta();
    	}
    	return result;
    }
    */

    public String getPergunta(PathComparacao path) {
    	String result;
    	String complemento = getComplementoPergunta(path);
    	if (complemento.equals("")) {
    		result = path.getSite().getPergunta();
    	} else {
    		result = complemento;
    	}
    	return result;
    }

    public String getComplementoPergunta(SiteHost site, String locale) {
    	String result = "";
    	PathComparacao pathSite = getPathComparacao(site, locale);
    	result = pathSite.getComplementoPergunta();
    	if (result == null) {
    		result = "";
    	}

    	return result;
    }

    public String getComplementoPergunta(PathComparacao path) {
    	String result = "";
    	result = path.getComplementoPergunta();
    	if (result == null) {
    		result = "";
    	}

    	return result;
    }

    public ArrayList<VotoComparacaoProduto> getListVotoComparacaoProdutos(Long idProduto) {
    	ArrayList<VotoComparacaoProduto> result = new ArrayList<VotoComparacaoProduto>(0);
    	if (getListVotoComparacaoProdutos() != null) {
	    	for (VotoComparacaoProduto v: getListVotoComparacaoProdutos()) {
	    		if (v.getIdProduto().equals(idProduto)) {
	    			result.add(v);
	    		}
	    	}
    	}
    	return result;
    }

    public boolean possuiIdCommentFB(String idCommentFB) {
    	boolean result = false;
    	if (getListVotoComparacaoProdutos() != null) {
	    	for (VotoComparacaoProduto v: getListVotoComparacaoProdutos()) {
	    		if (v.getIdCommentFB().equals(idCommentFB)) {
	    			result = true;
	    			break;
	    		}
	    	}
    	}
    	return result;
    }

    public long getNumVotosNoProduto(Long idProduto) {
    	long result = 0;
    	if (getListVotoComparacaoProdutos() != null) {
	    	for (VotoComparacaoProduto v: getListVotoComparacaoProdutos()) {
	    		if (v.getIdProduto().equals(idProduto)) {
	    			result++;
	    		}
	    	}
    	}
    	return result;
    }

    public long[] getNumVotos() {
    	// numero de votos no produto1 esta em long[0], em produto2 esta em long[1] etc..
    	long[] result = new long[listProdutosComp.size()];
    	if (getListVotoComparacaoProdutos() != null) {
	    	for (VotoComparacaoProduto v: getListVotoComparacaoProdutos()) {
	    		for (int i = 0; i < listProdutosComp.size(); i++) {
	    			if (v.getIdProduto().equals(listProdutosComp.get(i))) {
	    				result[i]++;
	    				break;
	    			}
	    		}
	    	}
    	}
    	return result;
    }

    public long[] getNumVotosAnonimos(long idUsuarioAnonimo) {
    	// numero de votos no produto1 esta em long[0], em produto2 esta em long[1] etc..
    	long[] result = new long[listProdutosComp.size()];
    	if (getListVotoComparacaoProdutos() != null) {
	    	for (VotoComparacaoProduto v: getListVotoComparacaoProdutos()) {
	    		if (v.getIdUsuario().equals(idUsuarioAnonimo)) {
		    		for (int i = 0; i < listProdutosComp.size(); i++) {
		    			if (v.getIdProduto().equals(listProdutosComp.get(i))) {
		    				result[i]++;
		    				break;
		    			}
		    		}
	    		}
	    	}
    	}
    	return result;
    }

    public long getNumComentariosTotal() {
    	long result = 0;
    	if (getListVotoComparacaoProdutos() != null) {
	    	for (VotoComparacaoProduto v: getListVotoComparacaoProdutos()) {
	    		if (v.getComentario() != null && !v.getComentario().equals("")) {
	    			result++;
	    		}
	    	}
    	}
    	return result;
    }

	public long getNumComentariosValidos(Long idProduto) {
		ArrayList<VotoComparacaoProduto> listVotoComparacao = getListVotoComparacaoProdutos(idProduto);
		long result = 0;
		for (VotoComparacaoProduto v: listVotoComparacao) {
			if (!v.getComentario().trim().equals("")) {
				result++;
			}
		}
		return result;
	}

    public String getPergunta(SiteHost site, String locale) {
    	//VERIFICA SE EXISTE A PERGUNTA TRADUZIDA NESTE SITE, CASO CONTRARIO UTILIZA O SITE ORIGINAL
    	//String result = getPergunta();
    	//System.out.println("getPergunta...");
    	PathComparacao path = getPathComparacao(site, locale);
    	String result = getPergunta(path);
    	boolean first = true;
    	for (Long p: listProdutosComp) {
    		//System.out.println("getPergunta... dentro do for..");
    		if (first) {
    			result += " " + mapNomeProdComp.get(p);
    		} else {
    			result += " " + ClientUtils.getConstant("ou", path.getSite().getLocale()[0]) + " " + mapNomeProdComp.get(p);
    		}
    		first = false;
    	}
    	result += "?";
    	return result;
    }

    public String getPerguntaHTML(SiteHost site, String locale) {
    	PathComparacao path = getPathComparacao(site, locale);
    	String result = getPergunta(path);
    	boolean first = true;
    	for (Long p: listProdutosComp) {
    		if (first) {
    			result += " <span>" + mapNomeProdComp.get(p) + "</span>";
    		} else {
    			result += " " + ClientUtils.getConstant("ou", path.getSite().getLocale()[0]) + " <span>" + mapNomeProdComp.get(p) + "</span>";
    		}
    		first = false;
    	}
    	result += "?";
    	return result;
    }
}